﻿namespace System.Web.Routing
{
    public static class RouteCollectionExtensions
    {
        public static Route MapRoute(this RouteCollection routes, string name, string url, IRouteHandler handler)
        {
            return MapRoute(routes, name, url, null /* defaults */, (object)null /* constraints */, handler);
        }

        public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, IRouteHandler handler)
        {
            return MapRoute(routes, name, url, defaults, (object)null /* constraints */, handler);
        }

        public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, IRouteHandler handler)
        {
            return MapRoute(routes, name, url, defaults, constraints, null /* namespaces */);
        }

        public static Route MapRoute(this RouteCollection routes, string name, string url, string[] namespaces, IRouteHandler handler)
        {
            return MapRoute(routes, name, url, null /* defaults */, null /* constraints */, namespaces, handler);
        }

        public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, string[] namespaces, IRouteHandler handler)
        {
            return MapRoute(routes, name, url, defaults, null /* constraints */, namespaces, handler);
        }

        public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces, IRouteHandler handler)
        {
            if (routes == null)
            {
                throw new ArgumentNullException("routes");
            }
            if (url == null)
            {
                throw new ArgumentNullException("url");
            }

            var route = new Route(url, handler)
                              {
                                  Defaults = new RouteValueDictionary(defaults),
                                  Constraints = new RouteValueDictionary(constraints)
                              };

            if ((namespaces != null) && (namespaces.Length > 0))
            {
                route.DataTokens = new RouteValueDictionary();
                route.DataTokens["Namespaces"] = namespaces;
            }

            routes.Add(name, route);

            return route;
        }

        public static string GetUrl(this RouteCollection routes, RequestContext context, string route, object values)
        {
            VirtualPathData pathData = routes.GetVirtualPath(context, route, new RouteValueDictionary(values));

            return pathData == null ? "" : pathData.VirtualPath;
        }

        public static string GetAbsoluteUrl(this RouteCollection routes, RequestContext context, string route, object values)
        {
            string url = routes.GetUrl(context, route, values);

            if (url != "")
            {
                Uri uri = context.HttpContext.Request.Url;
                var uriBuilder = new UriBuilder(uri.Scheme, uri.Host, uri.Port) {Path = url};

                url = uriBuilder.Uri.ToString();
            }

            return url;
        }
    }
}